﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Collections.Specialized;

namespace StateGrid
{
    public class Catalog
    {
        public string Code;
        public string Name;
        public string Description;
    }

    public delegate T QueryParser<T>(string value);

    public class CommonPage : Page
    {
        protected void CheckLogin()
        {
        }

        /// <summary>
        /// 给指定的URL增加query参数
        /// </summary>
        /// <param name="baseURL">基楚URL</param>
        /// <param name="querys">参数列表，query的key和value成对出现</param>
        /// <returns>修改后的URL</returns>
        protected string BuildURL(string baseURL, params string[] querys)
        {
            string[] path_query = baseURL.Split('?');

            NameValueCollection queryString;
            if (path_query.Length == 1)
                queryString = HttpUtility.ParseQueryString("");
            else
                queryString = HttpUtility.ParseQueryString(path_query[1]);
            for (int i = 0; i < querys.Length; i += 2)
            {
                string key = querys[i];
                string value = i + 1 < querys.Length ? querys[i + 1] : "";
                queryString[key] = HttpUtility.UrlEncodeUnicode(value);
            }

            return path_query[0] + "?" + queryString.ToString();
        }
        
        /// <summary>
        /// 负责解析query值的通用函数，返回解析后的数据结构。
        /// 主要作用是做了Try Catch的封装，可以简化实现。
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="key">key</param>
        /// <param name="parser">解析函数</param>
        /// <returns></returns>
        protected  T ParseQuery<T>(string key, QueryParser<T> parser)
        {
            T value;
            try
            {
                value = parser(Request[key]);
            }
            catch
            {
                value = default(T);
            }
            return value;
        }

        /// <summary>
        /// 负责解析query值的通用函数，返回解析后的数据结构。
        /// 主要作用是做了Try Catch的封装，可以简化实现。
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="key">key</param>
        /// <param name="parser">解析函数</param>
        /// <param name="back">解析失败时返回的默认值</param>
        /// <returns></returns>
        protected T ParseQuery<T>(string key, QueryParser<T> parser, T back)
        {
            T value;
            try
            {
                value = parser(Request[key]);
            }
            catch
            {
                value = back;
            }
            return value;
        }

        /// <summary>
        /// 解析整数query。对ParseIntegerQuery做的封装
        /// </summary>
        /// <param name="key">key</param>
        /// <returns></returns>
        protected int ParseIntegerQuery(string key)
        {
            return ParseQuery(key, s => int.Parse(s));
        }

        /// <summary>
        /// 解析字符query。对字符串做decode处理
        /// </summary>
        /// <param name="key">key</param>
        /// <returns></returns>
        protected string ParseStringQuery(string key)
        {
            string value = Request[key];
            if (value == null)
                value = "";
            return HttpUtility.UrlDecode(value);
        }

        private void CheckFail(string message)
        {
            throw new Exception(message);
        }

        protected void CheckNotEmpty(object item, string message)
        {
            if (item == null)
                CheckFail(message);

            if (item is string && (item as string) == "")
                CheckFail(message);
        }

        protected void Check(bool condition, string message)
        {
            if (!condition)
                CheckFail(message);
        }

        private void AssertFail(string message)
        {
            string url = BuildURL(GlobalVariables.GlobalResource.ERROR_PAGE, "message", message);
            Response.Redirect(url);
        }

        protected void AssertNotEmpty(object item, string message)
        {
            if (item == null)
                AssertFail(message);

            if (item is string && (item as string) == "")
                AssertFail(message);
        }

        protected void Assert(bool condition, string message)
        {
            if (!condition)
                AssertFail(message);
        }
    }

}